/*
 *  Copyright (c) 1998, Regents of the University of California
 *  All rights reserved.
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the name of the University of California, Berkeley nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.demis.troll;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @version 1.0
 * @author <a href="mailto:demis27@demis27.net">Stéphane kermabon</a>
 */
public final class ObjectModelHelper {

    private final Log logger = LogFactory.getLog(ObjectModelHelper.class);

    private static ObjectModelHelper instance = new ObjectModelHelper();

    private ObjectModelHelper() {
        // no op
    }

    public static ObjectModelHelper getInstance() {
        return instance;
    }

    public Set<PackageDescriptor> getPackageDependencies(ClassDescriptor classDescriptor)  {
        logger.debug("call getPackageDependencies for classDescriptor " + classDescriptor.getClassName());
        Set<PackageDescriptor> packages = new HashSet<PackageDescriptor>();

        Set<ClassDescriptor> classes = getClassDependencies(classDescriptor);
        for (ClassDescriptor classDescriptorDependence : classes) {
            if (!classDescriptor.getPackageDescriptor().equals(classDescriptorDependence.getPackageDescriptor())) {
                packages.add(classDescriptorDependence.getPackageDescriptor());
                logger.debug("find package : " + classDescriptorDependence.getPackageDescriptor().getName() + " dependence of : " + classDescriptor.getClassName());
            }
            else {
                logger.debug("same package : " + classDescriptorDependence.getClassName() + " dependence of : " + classDescriptor.getClassName());
            }
        }

        return packages;
    }
    
    public Set<ClassDescriptor> getClassDependencies(ClassDescriptor classDescriptor)  {
        logger.debug("call getClassDependencies for classDescriptor " + classDescriptor.getClassName());
        Set<ClassDescriptor> classes = new HashSet<ClassDescriptor>();

        List<RelationDescriptor> leftRelations = classDescriptor.getLeftRelations();
        for (RelationDescriptor leftRelation : leftRelations) {
            Set<PropertyDescriptor> properties = leftRelation.getRightProperties();
            for (PropertyDescriptor property : properties) {
                classes.add(property.getClassDescriptor());
                logger.debug("find class : " + property.getClassDescriptor() + " dependence of : " + classDescriptor.getClassName());
            }
        }

        List<RelationDescriptor> rightRelations = classDescriptor.getRightRelations();
        for (RelationDescriptor rightRelation : rightRelations) {
            Set<PropertyDescriptor> properties = rightRelation.getLeftProperties();
            for (PropertyDescriptor property : properties) {
                classes.add(property.getClassDescriptor());
                logger.debug("find class : " + property.getClassDescriptor().getClassName() + " dependence of : " + classDescriptor.getClassName());
            }
        }

        return classes;
    }
}
